package com.kongchengji.zhanguafou.service;

import com.kongchengji.zhanguafou.constant.WxInfo;
import com.kongchengji.zhanguafou.dao.QuartzDAO;
import com.kongchengji.zhanguafou.dao.StationDAO;
import com.kongchengji.zhanguafou.domain.*;
import com.kongchengji.zhanguafou.utils.BuildCustomerMsgUtil;
import com.kongchengji.zhanguafou.utils.FormatTimeUtil;
import com.kongchengji.zhanguafou.utils.GetStationUtil;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class StationService {
    @Autowired
    JobService jobService;
    @Autowired
    QuartzDAO quartzDAO;
    @Autowired
    StationDAO stationDAO;

    /**
     * 验证网站的合法性
     * @param url 网站网址
     * @return
     */
    public boolean validateStation(String url) {
        StationInfoDO stationInfoDO = GetStationUtil.get(url);
        if(stationInfoDO == null) {
            return false;
        }
        return true;
    }

    public Result saveStationConfig(StationDO stationDO) {
        boolean result = validateStation(stationDO.getUrl());
        if(!result) {
            return Result.error("请输入正确的网站域名");
        }
        //1.构造station任务quartzDO对象。
        QuartzDO quartzDO = buildQuartz(stationDO.getOpenId(), stationDO, "com.kongchengji.zhanguafou.quartz.ListenStationScheduleTask");
        //2.根据网址判断数据库中是否存在了该任务,不存在就将quartz保存数据库并启动监控。
        Example example = new Example(QuartzDO.class);
        example.createCriteria()
                .andEqualTo("jobName", quartzDO.getJobName());
        int count = quartzDAO.selectCountByExample(example);
        if (count != 0) {
            return Result.error("该网站已添加,如果未启动监控,请直接在监控列表中启动");
        }
        quartzDAO.insertSelective(quartzDO);
        //启动任务
        jobService.save(quartzDO);
        //3.将stationDO对象保存数据库，用于后续用户手动查询数据。
        stationDAO.insertSelective(stationDO);
        return Result.ok("站点监控添加成功");
    }

    /**
     * 查询用户监控的站点数据
     *
     * @param map 微信带来的的数据
     * @return 返回微信能识别的格式化的数据
     */
    public String selectStation(Map<String, String> map) {
        String toUserName = map.get("ToUserName");
        String openId = map.get("FromUserName");
        Example example = new Example(QuartzDO.class);
        example.createCriteria().andEqualTo("openId", openId).andEqualTo("jobGroup","Get");
        List<QuartzDO> quartzDOS = quartzDAO.selectByExample(example);
        //构造返回的数据
        String defaultMsg = "客官别急,正在查询,请稍等";
        if (quartzDOS.size() == 0) {
            defaultMsg = "你还未添加监控,请先添加";
        } else {
            //耗时操作,如果5秒内微信服务器得不到响应会重试,并在公众号中出现提供的服务出现故障的提示,所以异步执行。
            StringBuilder stringBuilder = new StringBuilder();
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (QuartzDO quartzDO : quartzDOS) {
                        //调用系统命令获得结果
                        StationInfoDO stationInfoDO = GetStationUtil.get(quartzDO.getUrl());
                        if (stationInfoDO != null) {
                            stringBuilder.append(
                                    "网址:" + quartzDO.getUrl() + "\n" +
                                            "站名: " + quartzDO.getName() + "\n" +
                                            "状态码: " + stationInfoDO.getCode() + "\n" +
                                            "解析时间: " + stationInfoDO.getParseTime() + "s\n" +
                                            "连接时间: " + stationInfoDO.getConnectTime() + "s\n" +
                                            "下载时间: " + stationInfoDO.getDownLoadTime() + "s\n");
                        }
                    }
                    String contentJson = BuildCustomerMsgUtil.buildMessage(stringBuilder.toString(), openId);
                    RequestBody requestBody =
                            FormBody.create(MediaType.parse("application/json;charset=utf-8"), contentJson);
                    Request request = new Request
                            .Builder()
                            .url("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + WxInfo.accessToken.getToken())
                            .post(requestBody)
                            .build();
                    OkHttpClient okHttpClient = new OkHttpClient();
                    try {
                        okHttpClient.newCall(request).execute();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

            });
            t.start();
        }
        String result = String
                .format(
                        "<xml>" +
                                "<ToUserName><![CDATA[%s]]></ToUserName>" +
                                "<FromUserName><![CDATA[%s]]></FromUserName>" +
                                "<CreateTime>%s</CreateTime>" +
                                "<MsgType><![CDATA[text]]></MsgType>" +
                                "<Content><![CDATA[%s]]></Content>" +
                                "</xml>",
                        openId, toUserName, FormatTimeUtil.getFormatTime(),
                        defaultMsg);
        return result;
    }


    /**
     * 根据时间表达式构造quartz对象，并将quartz对象和server对象保存数据库
     *
     * @param stationDO 监控对象
     * @param openId    该任务的归属
     * @param clazz     实际执行的任务类
     * @return
     */
    private QuartzDO buildQuartz(String openId, StationDO stationDO, String clazz) {
        //根据用户所选的时间组成cron表达式
        String cron = "0 0/" + stationDO.getInterval() + " * * * ?";
        QuartzDO quartz = new QuartzDO();
        //组成任务的唯一标识
        quartz.setJobName("Get" + stationDO.getUrl() + openId);
        quartz.setJobGroup("Get");
        quartz.setDescription("测试网站打开网页的各种参数详情");
        quartz.setJobClassName(clazz);
        quartz.setOpenId(openId);
        quartz.setUrl(stationDO.getUrl());
        quartz.setName(stationDO.getName());
        quartz.setCronExpression(cron);
        return quartz;
    }

}
